"""
企业级金融数据MCP服务系统 - 主服务入口
提供完整的金融数据查询工具集，基于FastMCP框架构建
支持股票、指数、基金、债券等多种金融数据类型的查询和分析功能
包含25个专业工具：股票11个、指数5个、基金5个、债券4个
"""

import asyncio
import logging
from typing import List, Dict, Any, Optional
from datetime import datetime, date, timedelta
from decimal import Decimal

from fastmcp import FastMCP, Context
from sqlalchemy import select, and_, or_, desc, asc, extract

# 核心组件导入
from src.core.config import get_settings
from src.core.database import db_manager, init_database, close_database
from src.core.cache import cache_manager

# 数据模型导入
from src.models.stock import (
    StockBasicInfo, StockDailyData, StockFinancialData,
    StockHolderData, StockDividendData, StockMarginData
)
from src.models.index import (
    IndexBasicInfo, IndexDailyData, IndexMinuteData,
    IndexConstituent, IndexValuation, IndexPerformance
)
from src.models.fund import (
    FundBasicInfo, FundNetValue, FundPortfolio,
    FundPerformance, FundManager, FundDividend
)
from src.models.bond import (
    BondBasicInfo, BondDailyData, BondConvertibleData,
    BondYieldData, BondIssueData
)

# DAO层导入
from src.dao.stock import (
    StockBasicInfoDAO, StockDailyDataDAO, StockFinancialDataDAO,
    StockHolderDataDAO, StockDividendDataDAO, StockMarginDataDAO
)
from src.dao.cached_dao import get_cached_dao_factory, create_cached_dao_config

# 日志配置
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# 全局组件实例
settings = None
cached_dao_factory = None

# MCP应用实例
app = FastMCP("企业级金融数据MCP服务")


async def initialize_services():
    """初始化所有服务组件"""
    global settings, db_manager, cache_manager, cached_dao_factory
    
    try:
        # 加载配置
        settings = get_settings()
        logger.info(f"配置加载完成: {settings.mcp.service_name} v{settings.mcp.service_version}")
        
        # 初始化数据库连接
        await db_manager.initialize()
        logger.info("数据库连接初始化完成")
        
        # 初始化缓存连接
        await cache_manager.initialize()
        logger.info("缓存系统初始化完成")
        
        # 创建缓存DAO工厂
        cached_dao_factory = get_cached_dao_factory()
        logger.info("缓存DAO工厂初始化完成")
        
        logger.info("所有服务组件初始化完成")
        
    except Exception as e:
        logger.error(f"服务初始化失败: {e}")
        raise


def model_to_dict(model_instance) -> Dict[str, Any]:
    """将模型实例转换为字典，字段名使用中文描述"""
    if not model_instance:
        return {}
    
    result = {}
    
    # 根据模型类型进行字段映射
    if isinstance(model_instance, StockBasicInfo):
        result = {
            "股票代码": model_instance.stock_code,
            "股票名称": model_instance.stock_name,
            "交易所": model_instance.exchange,
            "市场类型": model_instance.market_type,
            "行业": model_instance.industry,
            "上市日期": model_instance.list_date.isoformat() if model_instance.list_date else None,
            "是否活跃": model_instance.is_active,
            "行业分类": model_instance.industry,
            "概念板块": model_instance.concept,
            "数据来源": model_instance.data_source,
            "数据质量评分": model_instance.data_quality_score,
            "数据状态": model_instance.data_status,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None,
            "更新时间": model_instance.updated_at.isoformat() if model_instance.updated_at else None
        }
    
    elif isinstance(model_instance, StockDailyData):
        result = {
            "股票代码": model_instance.stock_code,
            "交易日期": model_instance.trade_date.isoformat() if model_instance.trade_date else None,
            "开盘价": float(model_instance.open_price) if model_instance.open_price else None,
            "最高价": float(model_instance.high_price) if model_instance.high_price else None,
            "最低价": float(model_instance.low_price) if model_instance.low_price else None,
            "收盘价": float(model_instance.close_price) if model_instance.close_price else None,
            "前收盘价": float(model_instance.pre_close) if model_instance.pre_close else None,
            "涨跌额": float(model_instance.change) if model_instance.change else None,
            "涨跌幅": float(model_instance.pct_chg) if model_instance.pct_chg else None,
            "成交量": float(model_instance.volume) if model_instance.volume else None,
            "成交额": float(model_instance.amount) if model_instance.amount else None,
            "换手率": float(model_instance.turnover_rate) if model_instance.turnover_rate else None,
            "总市值": float(model_instance.total_mv) if model_instance.total_mv else None,
            "流通市值": float(model_instance.circ_mv) if model_instance.circ_mv else None,
            "数据来源": model_instance.data_source,
            "数据质量评分": model_instance.data_quality_score,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, StockFinancialData):
        result = {
            "股票代码": model_instance.stock_code,
            "报告期": model_instance.report_period.isoformat() if model_instance.report_period else None,
            "总资产": float(model_instance.total_assets) if model_instance.total_assets else None,
            "总负债": float(model_instance.total_liab) if model_instance.total_liab else None,
            "净资产": float(model_instance.total_equity) if model_instance.total_equity else None,
            "营业收入": float(model_instance.revenue) if model_instance.revenue else None,
            "净利润": float(model_instance.net_profit) if model_instance.net_profit else None,
            "每股收益": float(model_instance.eps) if model_instance.eps else None,
            "每股净资产": float(model_instance.bps) if model_instance.bps else None,
            "净资产收益率": float(model_instance.roe) if model_instance.roe else None,
            "总资产收益率": float(model_instance.roa) if model_instance.roa else None,
            "毛利率": float(model_instance.gross_margin) if model_instance.gross_margin else None,
            "净利率": float(model_instance.net_margin) if model_instance.net_margin else None,
            "资产负债率": float(model_instance.debt_ratio) if model_instance.debt_ratio else None,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, StockDividendData):
        result = {
            "股票代码": model_instance.stock_code,
            "除权除息日": model_instance.ex_date.isoformat() if model_instance.ex_date else None,
            "股权登记日": model_instance.record_date.isoformat() if model_instance.record_date else None,
            "现金分红": float(model_instance.cash_div) if model_instance.cash_div else None,
            "股票分红": float(model_instance.stock_div) if model_instance.stock_div else None,
            "股票转增": float(model_instance.stock_transfer) if model_instance.stock_transfer else None,
            "分红方案": model_instance.div_plan,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, StockHolderData):
        result = {
            "股票代码": model_instance.stock_code,
            "报告期": model_instance.report_period.isoformat() if model_instance.report_period else None,
            "股东名称": model_instance.holder_name,
            "股东类型": model_instance.holder_type,
            "持股数量": float(model_instance.hold_amount) if model_instance.hold_amount else None,
            "持股比例": float(model_instance.hold_ratio) if model_instance.hold_ratio else None,
            "股东类型": model_instance.holder_type,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, StockMarginData):
        result = {
            "股票代码": model_instance.stock_code,
            "交易日期": model_instance.trade_date.isoformat() if model_instance.trade_date else None,
            "融资余额": float(model_instance.rzye) if model_instance.rzye else None,
            "融券余额": float(model_instance.rqye) if model_instance.rqye else None,
            "融资买入额": float(model_instance.rzmre) if model_instance.rzmre else None,
            "融券卖出量": float(model_instance.rqmcl) if model_instance.rqmcl else None,
            "融资融券余额": float(model_instance.rzrqye) if model_instance.rzrqye else None,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, IndexBasicInfo):
        result = {
            "指数代码": model_instance.index_code,
            "指数名称": model_instance.index_name,
            "指数类型": model_instance.index_type,
            "指数分类": model_instance.index_category,
            "基准日期": model_instance.base_date.isoformat() if model_instance.base_date else None,
            "基准点数": float(model_instance.base_point) if model_instance.base_point else None,
            "发布日期": model_instance.launch_date.isoformat() if model_instance.launch_date else None,
            "计算方法": model_instance.calculation_method,
            "样本数量": model_instance.sample_size,
            "发布机构": model_instance.publisher,
            "交易所代码": model_instance.exchange_code,
            "币种": model_instance.currency,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, IndexDailyData):
        result = {
            "指数代码": model_instance.index_code,
            "交易日期": model_instance.trade_date.isoformat() if model_instance.trade_date else None,
            "开盘点数": float(model_instance.open_point) if model_instance.open_point else None,
            "最高点数": float(model_instance.high_point) if model_instance.high_point else None,
            "最低点数": float(model_instance.low_point) if model_instance.low_point else None,
            "收盘点数": float(model_instance.close_point) if model_instance.close_point else None,
            "前收盘点数": float(model_instance.pre_close_point) if model_instance.pre_close_point else None,
            "涨跌点数": float(model_instance.change_point) if model_instance.change_point else None,
            "涨跌幅": float(model_instance.change_pct) if model_instance.change_pct else None,
            "成交量": model_instance.volume if model_instance.volume else None,
            "成交额": float(model_instance.amount) if model_instance.amount else None,
            "总市值": float(model_instance.total_market_cap) if model_instance.total_market_cap else None,
            "流通市值": float(model_instance.float_market_cap) if model_instance.float_market_cap else None,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, IndexConstituent):
        result = {
            "指数代码": model_instance.index_code,
            "股票代码": model_instance.stock_code,
            "生效日期": model_instance.effective_date.isoformat() if model_instance.effective_date else None,
            "权重": float(model_instance.weight) if model_instance.weight else None,
            "纳入因子": float(model_instance.inclusion_factor) if model_instance.inclusion_factor else None,
            "行业代码": model_instance.industry_code,
            "行业名称": model_instance.industry_name,
            "是否有效": model_instance.is_active,
            "失效日期": model_instance.expiry_date.isoformat() if model_instance.expiry_date else None,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, FundBasicInfo):
        result = {
            "基金代码": model_instance.fund_code,
            "基金名称": model_instance.fund_name,
            "基金类型": model_instance.fund_type,
            "投资类型": model_instance.invest_type,
            "基金管理人": model_instance.manager_name,
            "基金托管人": model_instance.custodian,
            "成立日期": model_instance.setup_date.isoformat() if model_instance.setup_date else None,
            "到期日期": model_instance.due_date.isoformat() if model_instance.due_date else None,
            "管理费率": float(model_instance.management_fee) if model_instance.management_fee else None,
            "托管费率": float(model_instance.custodian_fee) if model_instance.custodian_fee else None,
            "基金规模": float(model_instance.fund_size) if model_instance.fund_size else None,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, FundNetValue):
        result = {
            "基金代码": model_instance.fund_code,
            "净值日期": model_instance.nav_date.isoformat() if model_instance.nav_date else None,
            "单位净值": float(model_instance.unit_nav) if model_instance.unit_nav else None,
            "累计净值": float(model_instance.accum_nav) if model_instance.accum_nav else None,
            "日增长率": float(model_instance.daily_return) if model_instance.daily_return else None,
            "申购状态": model_instance.purchase_status,
            "赎回状态": model_instance.redeem_status,
            "分红送配": model_instance.dividend_info,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, FundPerformance):
        result = {
            "基金代码": model_instance.fund_code,
            "统计日期": model_instance.stat_date.isoformat() if model_instance.stat_date else None,
            "近1日收益": float(model_instance.return_1d) if model_instance.return_1d else None,
            "近1周收益": float(model_instance.return_1w) if model_instance.return_1w else None,
            "近1月收益": float(model_instance.return_1m) if model_instance.return_1m else None,
            "近3月收益": float(model_instance.return_3m) if model_instance.return_3m else None,
            "近6月收益": float(model_instance.return_6m) if model_instance.return_6m else None,
            "近1年收益": float(model_instance.return_1y) if model_instance.return_1y else None,
            "近3年收益": float(model_instance.return_3y) if model_instance.return_3y else None,
            "成立以来收益": float(model_instance.return_since_inception) if model_instance.return_since_inception else None,
            "夏普比率": float(model_instance.sharpe_ratio) if model_instance.sharpe_ratio else None,
            "最大回撤": float(model_instance.max_drawdown) if model_instance.max_drawdown else None,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, BondBasicInfo):
        result = {
            "债券代码": model_instance.bond_code,
            "债券名称": model_instance.bond_name,
            "债券类型": model_instance.bond_type,
            "发行人": model_instance.issuer_name,
            "担保方式": model_instance.guarantee_type,
            "发行日期": model_instance.issue_date.isoformat() if model_instance.issue_date else None,
            "上市日期": model_instance.list_date.isoformat() if model_instance.list_date else None,
            "到期日期": model_instance.maturity_date.isoformat() if model_instance.maturity_date else None,
            "发行规模": float(model_instance.issue_amount) if model_instance.issue_amount else None,
            "票面利率": float(model_instance.coupon_rate) if model_instance.coupon_rate else None,
            "付息方式": model_instance.pay_method,
            "信用评级": model_instance.credit_rating,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, BondDailyData):
        result = {
            "债券代码": model_instance.bond_code,
            "交易日期": model_instance.trade_date.isoformat() if model_instance.trade_date else None,
            "开盘价": float(model_instance.open_price) if model_instance.open_price else None,
            "最高价": float(model_instance.high_price) if model_instance.high_price else None,
            "最低价": float(model_instance.low_price) if model_instance.low_price else None,
            "收盘价": float(model_instance.close_price) if model_instance.close_price else None,
            "前收盘价": float(model_instance.pre_close) if model_instance.pre_close else None,
            "涨跌额": float(model_instance.change) if model_instance.change else None,
            "涨跌幅": float(model_instance.pct_chg) if model_instance.pct_chg else None,
            "成交量": float(model_instance.volume) if model_instance.volume else None,
            "成交量": float(model_instance.volume) if model_instance.volume else None,
            "到期收益率": float(model_instance.ytm) if model_instance.ytm else None,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    elif isinstance(model_instance, BondYieldData):
        result = {
            "数据日期": model_instance.data_date.isoformat() if model_instance.data_date else None,
            "收益率类型": model_instance.yield_type,
            "期限": float(model_instance.term) if model_instance.term else None,
            "收益率": float(model_instance.yield_rate) if model_instance.yield_rate else None,
            "信用等级": model_instance.credit_level,
            "市场类型": model_instance.market_type,
            "数据来源": model_instance.data_source_detail,
            "数据来源": model_instance.data_source,
            "创建时间": model_instance.created_at.isoformat() if model_instance.created_at else None
        }
    
    else:
        # 通用处理：直接转换所有属性
        for column in model_instance.__table__.columns:
            value = getattr(model_instance, column.name)
            if isinstance(value, (date, datetime)):
                result[column.name] = value.isoformat()
            elif isinstance(value, Decimal):
                result[column.name] = float(value)
            else:
                result[column.name] = value
    
    return result


@app.tool()
async def get_stock_basic_info(
    ctx: Context,
    symbol: Optional[str] = None,
    market: Optional[str] = None,
    name_pattern: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取股票基本信息
    
    Args:
        symbol: 股票代码，可选
        market: 市场类型（如：主板、创业板），可选
        name_pattern: 股票名称模糊搜索，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        股票基本信息列表，包含股票代码、名称、交易所、行业等信息
    """
    try:
        async with db_manager.get_session() as session:
            # 创建DAO实例
            dao = StockBasicInfoDAO(session, StockBasicInfo)
            
            from sqlalchemy import select, and_, or_
            
            results = []
            
            if symbol:
                # 按股票代码查询
                query = select(StockBasicInfo).where(StockBasicInfo.stock_code == symbol)
                result = await session.execute(query)
                stock_list = result.scalars().all()
                results.extend(stock_list)
            elif market:
                # 按市场查询
                query = select(StockBasicInfo).where(StockBasicInfo.market_type == market).limit(limit)
                result = await session.execute(query)
                stock_list = result.scalars().all()
                results.extend(stock_list)
            elif name_pattern:
                # 按名称模糊搜索
                query = select(StockBasicInfo).where(StockBasicInfo.stock_name.like(f'%{name_pattern}%')).limit(limit)
                result = await session.execute(query)
                stock_list = result.scalars().all()
                results.extend(stock_list)
            else:
                # 获取所有活跃股票
                query = select(StockBasicInfo).where(StockBasicInfo.is_active == True).limit(limit)
                result = await session.execute(query)
                stock_list = result.scalars().all()
                results.extend(stock_list)
            
            # 转换为字典格式
            return [model_to_dict(stock) for stock in results]
            
    except Exception as e:
        logger.error(f"获取股票基本信息失败: {e}")
        return [{"错误": f"获取股票基本信息失败: {str(e)}"}]


@app.tool()
async def get_stock_daily_data(
    ctx: Context,
    symbol: str,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取股票日线交易数据
    
    Args:
        symbol: 股票代码，必填
        start_date: 开始日期，格式YYYY-MM-DD，可选
        end_date: 结束日期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        股票日线数据列表，包含开盘价、收盘价、成交量等信息
    """
    try:
        async with db_manager.get_session() as session:
            # 直接使用SQLAlchemy查询
            
            from sqlalchemy import select, and_, desc
            
            if start_date and end_date:
                # 按日期范围查询
                start_dt = datetime.strptime(start_date, "%Y-%m-%d").date()
                end_dt = datetime.strptime(end_date, "%Y-%m-%d").date()
                query = select(StockDailyData).where(
                    and_(
                        StockDailyData.stock_code == symbol,
                        StockDailyData.trade_date >= start_dt,
                        StockDailyData.trade_date <= end_dt
                    )
                ).order_by(desc(StockDailyData.trade_date))
                result = await session.execute(query)
                results = result.scalars().all()
            else:
                # 获取最新数据
                query = select(StockDailyData).where(
                    StockDailyData.stock_code == symbol
                ).order_by(desc(StockDailyData.trade_date)).limit(limit)
                result = await session.execute(query)
                results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取股票日线数据失败: {e}")
        return [{"错误": f"获取股票日线数据失败: {str(e)}"}]


@app.tool()
async def get_stock_financial_data(
    ctx: Context,
    symbol: str,
    years: int = 5
) -> List[Dict[str, Any]]:
    """
    获取股票财务数据
    
    Args:
        symbol: 股票代码，必填
        years: 获取年数，默认5年
    
    Returns:
        股票财务数据列表，包含总资产、净利润、ROE等财务指标
    """
    try:
        async with db_manager.get_session() as session:
            # 直接使用SQLAlchemy查询
            
            from sqlalchemy import select, desc
            
            # 获取历史财务数据
            end_date = datetime.now().date()
            start_date = end_date - timedelta(days=years * 365)
            
            query = select(StockFinancialData).where(
                and_(
                    StockFinancialData.stock_code == symbol,
                    StockFinancialData.report_period >= start_date
                )
            ).order_by(desc(StockFinancialData.report_period))
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取股票财务数据失败: {e}")
        return [{"错误": f"获取股票财务数据失败: {str(e)}"}]


@app.tool()
async def get_stock_dividend_data(
    ctx: Context,
    symbol: str,
    years: int = 5
) -> List[Dict[str, Any]]:
    """
    获取股票分红数据
    
    Args:
        symbol: 股票代码，必填
        years: 获取年数，默认5年
    
    Returns:
        股票分红数据列表，包含现金分红、股票分红、股息率等信息
    """
    try:
        async with db_manager.get_session() as session:
            # 直接使用SQLAlchemy查询
            
            from sqlalchemy import select, desc
            
            # 获取分红历史
            end_date = datetime.now().date()
            start_date = end_date - timedelta(days=years * 365)
            
            query = select(StockDividendData).where(
                and_(
                    StockDividendData.stock_code == symbol,
                    StockDividendData.ex_date >= start_date
                )
            ).order_by(desc(StockDividendData.ex_date))
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取股票分红数据失败: {e}")
        return [{"错误": f"获取股票分红数据失败: {str(e)}"}]


@app.tool()
async def get_stock_holder_data(
    ctx: Context,
    symbol: str,
    holder_type: Optional[str] = None
) -> List[Dict[str, Any]]:
    """
    获取股票股东数据
    
    Args:
        symbol: 股票代码，必填
        holder_type: 股东类型筛选（如：基金、保险、券商），可选
    
    Returns:
        股票股东数据列表，包含股东名称、持股数量、持股比例等信息
    """
    try:
        async with db_manager.get_session() as session:
            # 构建查询条件
            query_conditions = []
            if symbol:
                query_conditions.append(StockHolderData.stock_code == symbol)
            if holder_type:
                query_conditions.append(StockHolderData.holder_type.contains(holder_type))
            
            # 构建查询
            if query_conditions:
                query = select(StockHolderData).where(and_(*query_conditions)).order_by(desc(StockHolderData.report_period)).limit(100)
            else:
                query = select(StockHolderData).order_by(desc(StockHolderData.report_period)).limit(100)
            
            # 执行查询
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取股票股东数据失败: {e}")
        return [{"错误": f"获取股票股东数据失败: {str(e)}"}]


@app.tool()
async def get_stock_margin_data(
    ctx: Context,
    symbol: str,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取股票融资融券数据
    
    Args:
        symbol: 股票代码，必填
        start_date: 开始日期，格式YYYY-MM-DD，可选
        end_date: 结束日期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        融资融券数据列表，包含融资余额、融券余额等信息
    """
    try:
        async with db_manager.get_session() as session:
            # 构建查询条件
            query_conditions = []
            if symbol:
                query_conditions.append(StockMarginData.stock_code == symbol)
            if start_date:
                start_dt = datetime.strptime(start_date, "%Y-%m-%d").date()
                query_conditions.append(StockMarginData.trade_date >= start_dt)
            if end_date:
                end_dt = datetime.strptime(end_date, "%Y-%m-%d").date()
                query_conditions.append(StockMarginData.trade_date <= end_dt)
            
            # 构建查询
            if query_conditions:
                query = select(StockMarginData).where(and_(*query_conditions)).order_by(desc(StockMarginData.trade_date)).limit(limit)
            else:
                query = select(StockMarginData).order_by(desc(StockMarginData.trade_date)).limit(limit)
            
            # 执行查询
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取融资融券数据失败: {e}")
        return [{"错误": f"获取融资融券数据失败: {str(e)}"}]


@app.tool()
async def get_high_volume_stocks(
    ctx: Context,
    trade_date: Optional[str] = None,
    min_volume: int = 1000000,
    limit: int = 50
) -> List[Dict[str, Any]]:
    """
    获取高成交量股票排行
    
    Args:
        trade_date: 交易日期，格式YYYY-MM-DD，默认最新交易日
        min_volume: 最小成交量阈值，默认100万手
        limit: 返回结果数量限制，默认50
    
    Returns:
        高成交量股票列表，按成交量降序排列
    """
    try:
        async with db_manager.get_session() as session:
            # 创建DAO实例
            dao = StockDailyDataDAO(session, StockDailyData)
            
            from sqlalchemy import select, desc
            
            if not trade_date:
                # 使用最新交易日
                trade_dt = datetime.now().date()
            else:
                trade_dt = datetime.strptime(trade_date, "%Y-%m-%d").date()
            
            # 获取高成交量股票
            query = select(StockDailyData).where(
                and_(
                    StockDailyData.trade_date == trade_dt,
                    StockDailyData.volume >= min_volume
                )
            ).order_by(desc(StockDailyData.volume)).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取高成交量股票失败: {e}")
        return [{"错误": f"获取高成交量股票失败: {str(e)}"}]


@app.tool()
async def get_price_change_ranking(
    ctx: Context,
    trade_date: Optional[str] = None,
    ranking_type: str = "涨幅",
    limit: int = 50
) -> List[Dict[str, Any]]:
    """
    获取股票涨跌幅排行榜
    
    Args:
        trade_date: 交易日期，格式YYYY-MM-DD，默认最新交易日
        ranking_type: 排行类型，"涨幅"或"跌幅"，默认"涨幅"
        limit: 返回结果数量限制，默认50
    
    Returns:
        股票涨跌幅排行列表，按涨跌幅排序
    """
    try:
        async with db_manager.get_session() as session:
            # 创建DAO实例
            dao = StockDailyDataDAO(session, StockDailyData)
            
            from sqlalchemy import select, desc, asc
            
            if not trade_date:
                # 使用最新交易日
                trade_dt = datetime.now().date()
            else:
                trade_dt = datetime.strptime(trade_date, "%Y-%m-%d").date()
            
            # 获取涨跌幅排行
            if ranking_type == "跌幅":
                query = select(StockDailyData).where(
                    StockDailyData.trade_date == trade_dt
                ).order_by(asc(StockDailyData.pct_chg)).limit(limit)
            else:
                query = select(StockDailyData).where(
                    StockDailyData.trade_date == trade_dt
                ).order_by(desc(StockDailyData.pct_chg)).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取涨跌幅排行失败: {e}")
        return [{"错误": f"获取涨跌幅排行失败: {str(e)}"}]


@app.tool()
async def get_high_roe_stocks(
    ctx: Context,
    min_roe: float = 0.15,
    report_date: Optional[str] = None,
    limit: int = 50
) -> List[Dict[str, Any]]:
    """
    获取高ROE股票列表
    
    Args:
        min_roe: 最小ROE阈值，默认15%
        report_date: 报告期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认50
    
    Returns:
        高ROE股票列表，按ROE降序排列
    """
    try:
        async with db_manager.get_session() as session:
            # 创建DAO实例
            dao = StockFinancialDataDAO(session, StockFinancialData)
            
            from sqlalchemy import select, desc
            
            if report_date:
                report_dt = datetime.strptime(report_date, "%Y-%m-%d").date()
                query = select(StockFinancialData).where(
                    and_(
                        StockFinancialData.roe >= min_roe,
                        StockFinancialData.report_period == report_dt
                    )
                ).order_by(desc(StockFinancialData.roe)).limit(limit)
            else:
                # 获取最新报告期的高ROE股票
                query = select(StockFinancialData).where(
                    StockFinancialData.roe >= min_roe
                ).order_by(desc(StockFinancialData.roe)).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取高ROE股票失败: {e}")
        return [{"错误": f"获取高ROE股票失败: {str(e)}"}]


@app.tool()
async def get_high_dividend_stocks(
    ctx: Context,
    min_dividend_yield: float = 0.05,
    year: Optional[int] = None,
    limit: int = 50
) -> List[Dict[str, Any]]:
    """
    获取高股息股票列表
    
    Args:
        min_dividend_yield: 最小股息率阈值，默认5%
        year: 年份筛选，可选
        limit: 返回结果数量限制，默认50
    
    Returns:
        高股息股票列表，按股息率降序排列
    """
    try:
        async with db_manager.get_session() as session:
            # 创建DAO实例
            dao = StockDividendDataDAO(session, StockDividendData)
            
            from sqlalchemy import select, desc, extract
            
            if year:
                # 按年份筛选
                query = select(StockDividendData).where(
                    and_(
                        StockDividendData.stock_transfer >= min_dividend_yield,
                        extract('year', StockDividendData.ex_date) == year
                    )
                ).order_by(desc(StockDividendData.stock_transfer)).limit(limit)
            else:
                # 获取所有高股息股票
                query = select(StockDividendData).where(
                    StockDividendData.stock_transfer >= min_dividend_yield
                ).order_by(desc(StockDividendData.stock_transfer)).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取高股息股票失败: {e}")
        return [{"错误": f"获取高股息股票失败: {str(e)}"}]


# ==================== 指数数据工具集 ====================

@app.tool()
async def get_index_basic_info(
    ctx: Context,
    index_code: Optional[str] = None,
    index_type: Optional[str] = None,
    name_pattern: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取指数基本信息
    
    Args:
        index_code: 指数代码，可选
        index_type: 指数类型（如：股票指数、债券指数），可选
        name_pattern: 指数名称模糊搜索，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        指数基本信息列表，包含指数代码、名称、类型、基准点数等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, or_
            
            results = []
            
            if index_code:
                # 按指数代码查询
                query = select(IndexBasicInfo).where(IndexBasicInfo.index_code == index_code)
                result = await session.execute(query)
                index_list = result.scalars().all()
                results.extend(index_list)
            elif index_type:
                # 按指数类型查询
                query = select(IndexBasicInfo).where(IndexBasicInfo.index_type == index_type).limit(limit)
                result = await session.execute(query)
                index_list = result.scalars().all()
                results.extend(index_list)
            elif name_pattern:
                # 按名称模糊搜索
                query = select(IndexBasicInfo).where(IndexBasicInfo.index_name.like(f'%{name_pattern}%')).limit(limit)
                result = await session.execute(query)
                index_list = result.scalars().all()
                results.extend(index_list)
            else:
                # 获取所有指数
                query = select(IndexBasicInfo).limit(limit)
                result = await session.execute(query)
                index_list = result.scalars().all()
                results.extend(index_list)
            
            # 转换为字典格式
            return [model_to_dict(index) for index in results]
            
    except Exception as e:
        logger.error(f"获取指数基本信息失败: {e}")
        return [{"错误": f"获取指数基本信息失败: {str(e)}"}]


@app.tool()
async def get_index_daily_data(
    ctx: Context,
    index_code: str,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取指数日线数据
    
    Args:
        index_code: 指数代码，必填
        start_date: 开始日期，格式YYYY-MM-DD，可选
        end_date: 结束日期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        指数日线数据列表，包含开盘点数、收盘点数、涨跌幅等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            if start_date and end_date:
                # 按日期范围查询
                start_dt = datetime.strptime(start_date, "%Y-%m-%d").date()
                end_dt = datetime.strptime(end_date, "%Y-%m-%d").date()
                query = select(IndexDailyData).where(
                    and_(
                        IndexDailyData.index_code == index_code,
                        IndexDailyData.trade_date >= start_dt,
                        IndexDailyData.trade_date <= end_dt
                    )
                ).order_by(desc(IndexDailyData.trade_date))
                result = await session.execute(query)
                results = result.scalars().all()
            else:
                # 获取最新数据
                query = select(IndexDailyData).where(
                    IndexDailyData.index_code == index_code
                ).order_by(desc(IndexDailyData.trade_date)).limit(limit)
                result = await session.execute(query)
                results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取指数日线数据失败: {e}")
        return [{"错误": f"获取指数日线数据失败: {str(e)}"}]


@app.tool()
async def get_index_components(
    ctx: Context,
    index_code: str,
    effective_date: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取指数成分股数据
    
    Args:
        index_code: 指数代码，必填
        effective_date: 生效日期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        指数成分股列表，包含股票代码、权重、行业等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            query_conditions = [IndexConstituent.index_code == index_code]
            
            if effective_date:
                eff_dt = datetime.strptime(effective_date, "%Y-%m-%d").date()
                query_conditions.append(IndexConstituent.effective_date == eff_dt)
            
            # 只获取有效的成分股
            query_conditions.append(IndexConstituent.is_active == True)
            
            query = select(IndexConstituent).where(
                and_(*query_conditions)
            ).order_by(desc(IndexConstituent.weight)).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取指数成分股失败: {e}")
        return [{"错误": f"获取指数成分股失败: {str(e)}"}]


@app.tool()
async def get_index_weight(
    ctx: Context,
    index_code: str,
    top_n: int = 20
) -> List[Dict[str, Any]]:
    """
    获取指数权重数据
    
    Args:
        index_code: 指数代码，必填
        top_n: 返回权重前N的成分股，默认20
    
    Returns:
        指数权重数据列表，按权重降序排列
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            # 获取权重最高的成分股
            query = select(IndexConstituent).where(
                and_(
                    IndexConstituent.index_code == index_code,
                    IndexConstituent.is_active == True
                )
            ).order_by(desc(IndexConstituent.weight)).limit(top_n)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取指数权重数据失败: {e}")
        return [{"错误": f"获取指数权重数据失败: {str(e)}"}]


@app.tool()
async def get_popular_indices(
    ctx: Context,
    index_category: Optional[str] = None,
    limit: int = 50
) -> List[Dict[str, Any]]:
    """
    获取热门指数列表
    
    Args:
        index_category: 指数分类筛选，可选
        limit: 返回结果数量限制，默认50
    
    Returns:
        热门指数列表，包含主要市场指数信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_
            
            query_conditions = []
            if index_category:
                query_conditions.append(IndexBasicInfo.index_category == index_category)
            
            if query_conditions:
                query = select(IndexBasicInfo).where(and_(*query_conditions)).limit(limit)
            else:
                # 获取主要指数（按发布机构和指数类型筛选）
                query = select(IndexBasicInfo).where(
                    or_(
                        IndexBasicInfo.publisher.like('%上交所%'),
                        IndexBasicInfo.publisher.like('%深交所%'),
                        IndexBasicInfo.publisher.like('%中证%'),
                        IndexBasicInfo.index_type.like('%综合%')
                    )
                ).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取热门指数失败: {e}")
        return [{"错误": f"获取热门指数失败: {str(e)}"}]


# ==================== 基金数据工具集 ====================

@app.tool()
async def get_fund_basic_info(
    ctx: Context,
    fund_code: Optional[str] = None,
    fund_type: Optional[str] = None,
    name_pattern: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取基金基本信息
    
    Args:
        fund_code: 基金代码，可选
        fund_type: 基金类型（如：股票型、债券型），可选
        name_pattern: 基金名称模糊搜索，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        基金基本信息列表，包含基金代码、名称、类型、规模等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, or_
            
            results = []
            
            if fund_code:
                # 按基金代码查询
                query = select(FundBasicInfo).where(FundBasicInfo.fund_code == fund_code)
                result = await session.execute(query)
                fund_list = result.scalars().all()
                results.extend(fund_list)
            elif fund_type:
                # 按基金类型查询
                query = select(FundBasicInfo).where(FundBasicInfo.fund_type == fund_type).limit(limit)
                result = await session.execute(query)
                fund_list = result.scalars().all()
                results.extend(fund_list)
            elif name_pattern:
                # 按名称模糊搜索
                query = select(FundBasicInfo).where(FundBasicInfo.fund_name.like(f'%{name_pattern}%')).limit(limit)
                result = await session.execute(query)
                fund_list = result.scalars().all()
                results.extend(fund_list)
            else:
                # 获取所有基金
                query = select(FundBasicInfo).limit(limit)
                result = await session.execute(query)
                fund_list = result.scalars().all()
                results.extend(fund_list)
            
            # 转换为字典格式
            return [model_to_dict(fund) for fund in results]
            
    except Exception as e:
        logger.error(f"获取基金基本信息失败: {e}")
        return [{"错误": f"获取基金基本信息失败: {str(e)}"}]


@app.tool()
async def get_fund_nav_data(
    ctx: Context,
    fund_code: str,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取基金净值数据
    
    Args:
        fund_code: 基金代码，必填
        start_date: 开始日期，格式YYYY-MM-DD，可选
        end_date: 结束日期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        基金净值数据列表，包含单位净值、累计净值、日增长率等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            if start_date and end_date:
                # 按日期范围查询
                start_dt = datetime.strptime(start_date, "%Y-%m-%d").date()
                end_dt = datetime.strptime(end_date, "%Y-%m-%d").date()
                query = select(FundNetValue).where(
                    and_(
                        FundNetValue.fund_code == fund_code,
                        FundNetValue.nav_date >= start_dt,
                        FundNetValue.nav_date <= end_dt
                    )
                ).order_by(desc(FundNetValue.nav_date))
                result = await session.execute(query)
                results = result.scalars().all()
            else:
                # 获取最新数据
                query = select(FundNetValue).where(
                    FundNetValue.fund_code == fund_code
                ).order_by(desc(FundNetValue.nav_date)).limit(limit)
                result = await session.execute(query)
                results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取基金净值数据失败: {e}")
        return [{"错误": f"获取基金净值数据失败: {str(e)}"}]


@app.tool()
async def get_fund_holding_data(
    ctx: Context,
    fund_code: str,
    report_period: Optional[str] = None,
    limit: int = 50
) -> List[Dict[str, Any]]:
    """
    获取基金持仓数据
    
    Args:
        fund_code: 基金代码，必填
        report_period: 报告期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认50
    
    Returns:
        基金持仓数据列表，包含持仓股票、持仓比例等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            query_conditions = [FundPortfolio.fund_code == fund_code]
            
            if report_period:
                report_dt = datetime.strptime(report_period, "%Y-%m-%d").date()
                query_conditions.append(FundPortfolio.report_date == report_dt)
            
            query = select(FundPortfolio).where(
                and_(*query_conditions)
            ).order_by(desc(FundPortfolio.nav_ratio)).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取基金持仓数据失败: {e}")
        return [{"错误": f"获取基金持仓数据失败: {str(e)}"}]


@app.tool()
async def get_fund_performance(
    ctx: Context,
    fund_code: str,
    stat_date: Optional[str] = None
) -> List[Dict[str, Any]]:
    """
    获取基金业绩数据
    
    Args:
        fund_code: 基金代码，必填
        stat_date: 统计日期，格式YYYY-MM-DD，可选
    
    Returns:
        基金业绩数据列表，包含各期收益率、夏普比率、最大回撤等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            query_conditions = [FundPerformance.fund_code == fund_code]
            
            if stat_date:
                stat_dt = datetime.strptime(stat_date, "%Y-%m-%d").date()
                query_conditions.append(FundPerformance.stat_date == stat_dt)
            
            query = select(FundPerformance).where(
                and_(*query_conditions)
            ).order_by(desc(FundPerformance.stat_date))
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取基金业绩数据失败: {e}")
        return [{"错误": f"获取基金业绩数据失败: {str(e)}"}]


@app.tool()
async def get_top_funds(
    ctx: Context,
    fund_type: Optional[str] = None,
    ranking_period: str = "1y",
    limit: int = 50
) -> List[Dict[str, Any]]:
    """
    获取优秀基金排行
    
    Args:
        fund_type: 基金类型筛选，可选
        ranking_period: 排行周期（1d/1w/1m/3m/6m/1y/3y），默认1年
        limit: 返回结果数量限制，默认50
    
    Returns:
        优秀基金排行列表，按指定周期收益率降序排列
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            # 根据排行周期选择对应的收益率字段
            order_field_map = {
                "1d": FundPerformance.return_1d,
                "1w": FundPerformance.return_1w,
                "1m": FundPerformance.return_1m,
                "3m": FundPerformance.return_3m,
                "6m": FundPerformance.return_6m,
                "1y": FundPerformance.return_1y,
                "3y": FundPerformance.return_3y
            }
            
            order_field = order_field_map.get(ranking_period, FundPerformance.return_1y)
            
            if fund_type:
                # 需要关联基金基本信息表来筛选基金类型
                query = select(FundPerformance).join(
                    FundBasicInfo, FundPerformance.fund_code == FundBasicInfo.fund_code
                ).where(
                    FundBasicInfo.fund_type == fund_type
                ).order_by(desc(order_field)).limit(limit)
            else:
                query = select(FundPerformance).order_by(desc(order_field)).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取优秀基金排行失败: {e}")
        return [{"错误": f"获取优秀基金排行失败: {str(e)}"}]


# ==================== 债券数据工具集 ====================

@app.tool()
async def get_bond_basic_info(
    ctx: Context,
    bond_code: Optional[str] = None,
    bond_type: Optional[str] = None,
    issuer_pattern: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取债券基本信息
    
    Args:
        bond_code: 债券代码，可选
        bond_type: 债券类型（如：国债、企业债），可选
        issuer_pattern: 发行人名称模糊搜索，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        债券基本信息列表，包含债券代码、名称、发行人、票面利率等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, or_
            
            results = []
            
            if bond_code:
                # 按债券代码查询
                query = select(BondBasicInfo).where(BondBasicInfo.bond_code == bond_code)
                result = await session.execute(query)
                bond_list = result.scalars().all()
                results.extend(bond_list)
            elif bond_type:
                # 按债券类型查询
                query = select(BondBasicInfo).where(BondBasicInfo.bond_type == bond_type).limit(limit)
                result = await session.execute(query)
                bond_list = result.scalars().all()
                results.extend(bond_list)
            elif issuer_pattern:
                # 按发行人模糊搜索
                query = select(BondBasicInfo).where(BondBasicInfo.issuer_name.like(f'%{issuer_pattern}%')).limit(limit)
                result = await session.execute(query)
                bond_list = result.scalars().all()
                results.extend(bond_list)
            else:
                # 获取所有债券
                query = select(BondBasicInfo).limit(limit)
                result = await session.execute(query)
                bond_list = result.scalars().all()
                results.extend(bond_list)
            
            # 转换为字典格式
            return [model_to_dict(bond) for bond in results]
            
    except Exception as e:
        logger.error(f"获取债券基本信息失败: {e}")
        return [{"错误": f"获取债券基本信息失败: {str(e)}"}]


@app.tool()
async def get_bond_price_data(
    ctx: Context,
    bond_code: str,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取债券价格数据
    
    Args:
        bond_code: 债券代码，必填
        start_date: 开始日期，格式YYYY-MM-DD，可选
        end_date: 结束日期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        债券价格数据列表，包含开盘价、收盘价、成交量、到期收益率等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            if start_date and end_date:
                # 按日期范围查询
                start_dt = datetime.strptime(start_date, "%Y-%m-%d").date()
                end_dt = datetime.strptime(end_date, "%Y-%m-%d").date()
                query = select(BondDailyData).where(
                    and_(
                        BondDailyData.bond_code == bond_code,
                        BondDailyData.trade_date >= start_dt,
                        BondDailyData.trade_date <= end_dt
                    )
                ).order_by(desc(BondDailyData.trade_date))
                result = await session.execute(query)
                results = result.scalars().all()
            else:
                # 获取最新数据
                query = select(BondDailyData).where(
                    BondDailyData.bond_code == bond_code
                ).order_by(desc(BondDailyData.trade_date)).limit(limit)
                result = await session.execute(query)
                results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取债券价格数据失败: {e}")
        return [{"错误": f"获取债券价格数据失败: {str(e)}"}]


@app.tool()
async def get_bond_yield_data(
    ctx: Context,
    bond_code: str,
    calc_date: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取债券收益率数据
    
    Args:
        bond_code: 债券代码，必填
        calc_date: 计算日期，格式YYYY-MM-DD，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        债券收益率数据列表，包含到期收益率、修正久期、凸性等信息
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, desc
            
            query_conditions = []
            
            if calc_date:
                calc_dt = datetime.strptime(calc_date, "%Y-%m-%d").date()
                query_conditions.append(BondYieldData.data_date == calc_dt)
            
            query = select(BondYieldData).where(
                and_(*query_conditions)
            ).order_by(desc(BondYieldData.data_date)).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取债券收益率数据失败: {e}")
        return [{"错误": f"获取债券收益率数据失败: {str(e)}"}]


@app.tool()
async def get_bond_rating_data(
    ctx: Context,
    bond_code: Optional[str] = None,
    credit_rating: Optional[str] = None,
    issuer_pattern: Optional[str] = None,
    limit: int = 100
) -> List[Dict[str, Any]]:
    """
    获取债券评级数据
    
    Args:
        bond_code: 债券代码，可选
        credit_rating: 信用评级筛选（如：AAA、AA+），可选
        issuer_pattern: 发行人名称模糊搜索，可选
        limit: 返回结果数量限制，默认100
    
    Returns:
        债券评级数据列表，包含债券基本信息和信用评级
    """
    try:
        async with db_manager.get_session() as session:
            from sqlalchemy import select, and_, or_
            
            query_conditions = []
            
            if bond_code:
                query_conditions.append(BondBasicInfo.bond_code == bond_code)
            if credit_rating:
                query_conditions.append(BondBasicInfo.credit_rating == credit_rating)
            if issuer_pattern:
                query_conditions.append(BondBasicInfo.issuer_name.like(f'%{issuer_pattern}%'))
            
            if query_conditions:
                query = select(BondBasicInfo).where(and_(*query_conditions)).limit(limit)
            else:
                # 获取有评级的债券
                query = select(BondBasicInfo).where(
                    BondBasicInfo.credit_rating.isnot(None)
                ).limit(limit)
            
            result = await session.execute(query)
            results = result.scalars().all()
            
            # 转换为字典格式
            return [model_to_dict(data) for data in results]
            
    except Exception as e:
        logger.error(f"获取债券评级数据失败: {e}")
        return [{"错误": f"获取债券评级数据失败: {str(e)}"}]


async def cleanup_services():
    """清理所有服务组件"""
    global db_manager, cache_manager
    
    try:
        if cache_manager:
            await cache_manager.close()
            logger.info("缓存系统已关闭")
        
        if db_manager:
            await db_manager.close()
            logger.info("数据库连接已关闭")
            
        logger.info("所有服务组件清理完成")
        
    except Exception as e:
        logger.error(f"服务清理失败: {e}")


async def main():
    """主函数 - 启动MCP服务"""
    # 配置日志
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.StreamHandler(),
            logging.FileHandler('financial_mcp_service.log')
        ]
    )
    
    logger.info("企业级金融数据MCP服务正在启动...")
    
    try:
        # 初始化服务
        await initialize_services()
        logger.info("企业级金融数据MCP服务启动完成")
        
        # 启动FastMCP服务
        app.run()
        
    except KeyboardInterrupt:
        logger.info("收到停止信号，正在关闭服务...")
    except Exception as e:
        logger.error(f"服务启动失败: {e}")
    finally:
        # 清理服务
        await cleanup_services()
        logger.info("企业级金融数据MCP服务已关闭")


if __name__ == "__main__":
    import asyncio
    asyncio.run(main())